﻿//Copyright (c) 2009, Offbeat Guides
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are 
//permitted provided that the following conditions are met:
//
//* Redistributions of source code must retain the above copyright notice, this list of 
//conditions and the following disclaimer.
//
//* Redistributions in binary form must reproduce the above copyright notice, this list 
//of conditions and the following disclaimer in the documentation and/or other materials 
//provided with the distribution.
//
//* Neither the name of Offbeat Guides nor the names of its contributors may be used to 
//endorse or promote products derived from this software without specific prior written 
//permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
//EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
//OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
//SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
//OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
//TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
//EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace Amazon.Services.S3
{
    public class FileInfo : Amazon.Services.S3.FileSystemInfo
    {
        #region Variables
        private Amazon.Services.S3.DirectoryInfo _directory;
        private Amazon.Services.S3.AccessControlModes _security;
        #endregion

        #region Properties
        public Uri PublicUrl
        {
            get { return new Uri(String.Format("http://s3.amazonaws.com/{0}/{1}", this.Bucket, this.Path)); }
        }

        public DirectoryInfo Directory
        {
            get
            {
                if (this._directory == null)
                { }
                return this._directory;
            }
        }

        public String DirectoryName
        {
            get { return this.Directory.Name; }
        }

        public Boolean ReadOnly { get; private set; }

        public Int64 Length { get; private set; }

        public AccessControlModes AccessControl
        {
            get { return this._security; }
            set
            {
                if (this._security == value)
                    return;

                FileSystemHelper.SetAccessControl(this.Client, this.Bucket, this.Path, value);
                this._security = value;
            }
        }
        #endregion

        #region Constructors and Finalizers
        internal FileInfo(ServiceClient client, String fullpath)
            : base(client, fullpath) { }

        internal FileInfo(ServiceClient client, String bucket, String path)
            : base(client, bucket, path) { }

        public FileInfo(AmazonAccount account, String fullpath)
            : base(new ServiceClient(account, S3Configuration.Default), fullpath) { }
        #endregion

        #region Methods
        public StreamWriter AppendText()
        {
            return new StreamWriter(new FileStream(this.Client.Account, this.FullName, FileMode.Append), Encoding.UTF8);
        }

        public FileStream Create()
        {
            this.Exists = true;
            return new FileStream(this.Client.Account, this.FullName, FileMode.Create);
        }

        public StreamWriter CreateText()
        {
            return new StreamWriter(new FileStream(this.Client.Account, this.FullName, FileMode.Create), Encoding.UTF8);
        }

        public FileStream Open(FileMode mode)
        {
            return this.Open(mode, FileAccess.ReadWrite, FileShare.None);
        }

        public FileStream Open(FileMode mode, FileAccess access)
        {
            return this.Open(mode, access, FileShare.None);
        }

        public FileStream Open(FileMode mode, FileAccess access, FileShare share)
        {
            return new FileStream(this.Client.Account, this.FullName, mode, access, share);
        }

        public FileStream OpenRead()
        {
            return new FileStream(this.Client.Account, this.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        public StreamReader OpenText()
        {
            return new StreamReader(new FileStream(this.Client.Account, this.FullName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read));
        }

        public FileStream OpenWrite()
        {
            return new FileStream(this.Client.Account, this.FullName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
        }
        #endregion

        #region Overriden Methods
        public override void Refresh()
        {
            base.Refresh();

            if(this.Exists)
                this._security = FileSystemHelper.GetAccessControl(this.Client, this.Bucket, this.Path);
        }

        public override void Delete()
        {
            File.Delete(this.Client.Account, this.FullName);
            this.Exists = false;
        }
        #endregion
    }
}
